﻿#include "../../GameObject/Camera.h"
#include "GameController.h"
#include <GLFW/glfw3.h>
#include "../../Event/Events.h"

using namespace Kriko;

float GameController::fCameraSpeed = 100.f;

GameController::GameController(Camera* camera)
{
    pCamera = camera;
    mousePosition = lastMousePosition = glm::vec2(0, 0);
    fSpeed = 5.0f;
    bFirstMouse = true;
}

void GameController::OnKeyEvent(IEventDataPtr eventPtr)
{
    auto keyEvent = std::dynamic_pointer_cast<KeyBroadDataBase>(eventPtr);
    if (keyEvent)
    {
        const int keyCode = keyEvent->GetKey();
        const int keyAction = keyEvent->GetAction();

        keyCodeArray[keyCode] = keyAction;
    }
}

void GameController::OnMouseMove(IEventDataPtr eventPtr)
{
    auto mouseEvent = std::dynamic_pointer_cast<MouseInputDataBase>(eventPtr);
    if (mouseEvent)
    {
        mousePosition = glm::vec2(mouseEvent->GetX(), mouseEvent->GetY()); 
    }
}

void GameController::OnMouseButton(IEventDataPtr eventPtr)
{
    auto mouseButton = std::dynamic_pointer_cast<MouseButtonDataBase>(eventPtr);
    if (mouseButton)
    {
        const int button = mouseButton->GetButton();
        const int action = mouseButton->GetAction();

        mouseButtonArray[button] = action;
    }
}

void GameController::Update(const TimeStep& deltaTime)
{
    if (!(*bCanControl))
        return;
    
    glm::vec3 position = pCamera->GetPosition();
    glm::vec3 front = pCamera->GetFront();
    glm::vec3 right = pCamera->GetRight();
    float pitch = pCamera->GetPitch();
    float yaw = pCamera->GetYaw();

    // mouse
    if (bFirstMouse)
    {
        lastMousePosition = mousePosition;
        bFirstMouse = false;
    }
    glm::vec2 mouseMovement = mousePosition - lastMousePosition;
    // key 
    if (keyCodeArray[GLFW_KEY_W])
    {
        position += front * fCameraSpeed * deltaTime.GetSecond() * 0.1f;
        pCamera->SetPosition(position);
    }
    if (keyCodeArray[GLFW_KEY_S])
    {
        position -= front * fCameraSpeed * deltaTime.GetSecond() * 0.1f;
        pCamera->SetPosition(position);
    }
    if (keyCodeArray[GLFW_KEY_A])
    {
        position -= right * fCameraSpeed * deltaTime.GetSecond() * 0.1f;
        pCamera->SetPosition(position);
    }
    if (keyCodeArray[GLFW_KEY_D])
    {
        position += right * fCameraSpeed * deltaTime.GetSecond() * 0.1f;
        pCamera->SetPosition(position);
    }

    if (mouseButtonArray[GLFW_MOUSE_BUTTON_RIGHT])
    {
        position.y += mouseMovement.y * fCameraSpeed * deltaTime.GetSecond() * 0.01f;
        pCamera->SetPosition(position);
    }
    if (mouseButtonArray[GLFW_MOUSE_BUTTON_LEFT])
    {
        pitch += mouseMovement.y * fCameraSpeed * deltaTime.GetSecond() * 0.05f;
        pitch = glm::clamp(pitch, -89.0f, 89.0f);
        yaw += mouseMovement.x * fCameraSpeed * deltaTime.GetSecond() * 0.05f;

        pCamera->SetPitch(pitch);
        pCamera->SetYaw(yaw);
    }

    lastMousePosition = mousePosition;
}




